#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;

class Socket
{
public:
    Socket(string server_ip, int16_t server_port)
        : client_sockaddr_len(sizeof(client))
    {
        // 填写网络字段
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = inet_addr(server_ip.c_str());
        server.sin_port = htons(server_port);
        // 创建套接字
        listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_sockfd < 0)
        {
            cerr << "套接字创建失败" << endl;
            exit(-1);
        }
        cout << "套接字创建成功" << endl;
        // 绑定
        int n = bind(listen_sockfd, (struct sockaddr *)&server, sizeof(server));
        if (n < 0)
        {
            cerr << "绑定失败" << endl;
            exit(-1);
        }
        cout << "绑定成功" << endl;
        // 设置套接字为监听状态
        int listen_code = listen(listen_sockfd, 2);
        if (listen_code < 0)
        {
            cerr << "设置监听状态失败" << endl;
            exit(-1);
        }
        cout << "设置监听状态成功" << endl;
    }
    // 处理方法
    string Server(char *inbuffer)
    {
        cout << "服务端收到信息 # " << inbuffer << endl;
        string outbuff = inbuffer;
        return outbuff;
    }

    // 通信方法
    void communication(int sockfd)
    {
        while (true)
        {
            char inbuffer[1024];
            ssize_t read_nums = read(sockfd, &inbuffer, sizeof(inbuffer));
            if (read_nums > 0)
            {
                // 读取成功
                inbuffer[read_nums] = '\0';
                // 业务处理
                string response = Server(inbuffer);
                // 返回响应
                int write_nums = write(sockfd, response.c_str(), response.size());
                if (write_nums < 0)
                {
                    cerr << "写入信息给客户端失败" << endl;
                }
            }
            else if (read_nums == 0)
            {
                cout << "客户端退出了" << endl;
                break;
            }
            else
            {
                cerr << "读取失败" << endl;
            }
        }
    }

    // 开始通信
    void Start()
    {
        while (true)
        {
            int sockfd = accept(listen_sockfd, (struct sockaddr *)&client, &client_sockaddr_len);
            if (sockfd < 0)
            {
                cerr << "获取连接失败" << endl;
                continue;
            }
            // 通信
            communication(sockfd);
            close(sockfd);
        }
    }

private:
    int listen_sockfd;
    struct sockaddr_in server;
    struct sockaddr_in client;
    socklen_t client_sockaddr_len;
};

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cerr << "正确用法: ./tcp_server server_port" << endl;
        exit(-1);
    }
    Socket sock("0.0.0.0", stoi(argv[1]));
    sock.Start();
    return 0;
}